// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: wsfuyibing <682805@qq.com>
// Date: 2024-08-16

package conf

import (
	"gitee.com/go-libs/config"
	"gitee.com/go-libs/db-xorm/db/commands/base"
)

var Model ModelConfig

type (
	// ModelConfig
	// is an interface for configuration operate.
	//
	// Path:
	//
	//   config/console.yaml
	//
	// Example:
	//
	//   commands:
	//     gen:model:
	//       fields:
	//         task.status:
	//           pkg: sketch/app
	//           type: app.Status
	//         task.concurrency:
	//           type: int32
	//         task.created_at:
	//           pkg: gitee.com/go-libs/db-xorm/db
	//           type: db.Datetime
	//       types:
	//         date:
	//           pkg: gitee.com/go-libs/db-xorm/db
	//           type: db.Date
	//         datetime:
	//           pkg: gitee.com/go-libs/db-xorm/db
	//           type: db.Datetime
	ModelConfig interface {
		// Get
		// returns a configured convertor in console.yaml.
		Get(field, typ string) *base.Convertor

		// Mapping
		// returns the builtin mapping.
		Mapping() Mapping
	}

	model struct {
		err      error
		Commands map[string]*ModelCommand `yaml:"commands"`
	}
)

// Get
// returns a configured convertor in console.yaml.
func (o *model) Get(field, typ string) (convertor *base.Convertor) {
	var has bool

	// Use configured convertor.
	if c, ok := o.Commands[base.CommandNameModel]; ok {
		// Primary for field.
		if convertor, has = c.Fields[field]; has {
			return
		}

		// Secondary for type.
		if convertor, has = c.Types[typ]; has {
			return
		}
	}

	// For builtin mapping.
	if convertor = builtinMapping.Get(typ); convertor != nil {
		return
	}

	// For undefined.
	convertor = builtinUndefined
	return
}

// Mapping
// returns the builtin mapping.
func (o *model) Mapping() Mapping {
	return builtinMapping
}

func (o *model) init() *model {
	o.err = config.Seek("console.yml", "console.yaml").ScanYaml(o)
	return o
}
